fix(desktop): 本条消息生成的文件卡对转义残留路径去重 - #2049
Conversation
实测场景(pr-watch session):powershell 包一层 node -e 的命令落库文本里, 路径带转义残留(C:\Users\...);同轮另一条命令用正斜杠形态。二者在 fs 层是同一文件(Windows 归并重复分隔符),但去重 key 未折叠连续反斜杠, 产生两个同名 chip。 - dedupeKeyForPath:Windows 形态折叠连续分隔符(UNC 头部 \ 保留); - canonicalizeWindowsShape:盘符路径的画布路径本身同步折叠——chip tooltip、 Explorer 定位与打开拿到干净的单反斜杠形态,MessageStream 与变更卡 exactPaths 的抑制比对也能对上。 用该 session 真实落库数据重放派生管线验证:registry.json 从 2 条收敛为 1 条。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: DavidShen <david@xd.com>
|
| Filename | Overview |
|---|---|
| apps/desktop/src/renderer/lib/generatedFiles.ts | 新增的 Windows 分隔符折叠可解决盘符路径重复,但会错误转换含反斜杠的 POSIX 路径,且未清理 UNC 输出路径。 |
| apps/desktop/src/renderer/tests/generatedFiles.test.ts | 新增了盘符和 UNC 回归测试,但 UNC 用例仅检查前缀,未断言测试标题所要求的内部重复分隔符折叠。 |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
A["命令文本中的路径候选"] --> B["resolveToolFilePath"]
B --> C["canonicalizeWindowsShape"]
C --> D["dedupeKeyForPath"]
D --> E{"Map 中已有 key?"}
E -- 否 --> F["保存 GeneratedFileRef.path"]
E -- 是 --> G["保留首个路径并丢弃后续候选"]
F --> H["生成文件 chip / 打开 / Explorer 定位"]
G --> H
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/renderer/lib/generatedFiles.ts:59-62
**POSIX 路径被错误折叠**
当 Linux 或 macOS 的合法路径包含字面反斜杠时,`abs.includes('\\')` 会将其当作 Windows 路径,进而折叠反斜杠并转为小写;两个仅在反斜杠数量或大小写上不同的文件会得到相同去重 key,导致后出现的生成文件 chip 被静默丢弃。
### Issue 2
apps/desktop/src/renderer/lib/generatedFiles.ts:74-77
**UNC 输出路径未规范化**
当首个 UNC 候选包含内部重复反斜杠时,去重 key 虽会折叠这些分隔符,但 `canonicalizeWindowsShape` 会原样保留该路径;去重后 chip tooltip、文件打开和 Explorer 定位仍会收到带转义残留的 UNC 路径。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(desktop): 本条消息生成的文件卡对转义残留路径去重" | Re-trigger Greptile
| // UNC 头部的 `\\` 是路径语义的一部分,保留。 | ||
| return abs | ||
| .replace(/\//g, '\\') | ||
| .replace(/(?<!^)\\{2,}/g, '\\') |
There was a problem hiding this comment.
当 Linux 或 macOS 的合法路径包含字面反斜杠时,abs.includes('\\') 会将其当作 Windows 路径,进而折叠反斜杠并转为小写;两个仅在反斜杠数量或大小写上不同的文件会得到相同去重 key,导致后出现的生成文件 chip 被静默丢弃。
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/lib/generatedFiles.ts
Line: 59-62
Comment:
**POSIX 路径被错误折叠**
当 Linux 或 macOS 的合法路径包含字面反斜杠时,`abs.includes('\\')` 会将其当作 Windows 路径,进而折叠反斜杠并转为小写;两个仅在反斜杠数量或大小写上不同的文件会得到相同去重 key,导致后出现的生成文件 chip 被静默丢弃。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.| // Explorer `/select` 与 chip 展示不该带转义残留。盘符形态不存在 UNC 头,可整段折叠。 | ||
| return /^[a-zA-Z]:[\\/]/.test(abs) | ||
| ? abs.replace(/\//g, '\\').replace(/\\{2,}/g, '\\') | ||
| : abs; |
There was a problem hiding this comment.
当首个 UNC 候选包含内部重复反斜杠时,去重 key 虽会折叠这些分隔符,但 canonicalizeWindowsShape 会原样保留该路径;去重后 chip tooltip、文件打开和 Explorer 定位仍会收到带转义残留的 UNC 路径。
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/desktop/src/renderer/lib/generatedFiles.ts
Line: 74-77
Comment:
**UNC 输出路径未规范化**
当首个 UNC 候选包含内部重复反斜杠时,去重 key 虽会折叠这些分隔符,但 `canonicalizeWindowsShape` 会原样保留该路径;去重后 chip tooltip、文件打开和 Explorer 定位仍会收到带转义残留的 UNC 路径。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Pull request overview
本 PR 修复桌面端消息流里「本条消息生成的文件」卡片在 Windows 场景下因路径形态不一致(正斜杠 vs 反斜杠、以及命令包装导致的连续反斜杠转义残留)而出现重复文件 chip 的问题,通过增强路径去重 key 与展示/打开用路径的归一化来收敛同一文件的多种文本形态。
Changes:
dedupeKeyForPath:在 Windows 形态路径上新增对连续分隔符(反斜杠 runs)的折叠,避免同一文件生成多个去重 key。canonicalizeWindowsShape:对盘符路径折叠连续分隔符,确保用于 tooltip/打开/定位的路径不携带转义残留。- 增加回归测试覆盖“转义残留双反斜杠 vs 正斜杠”与 UNC 场景。
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| apps/desktop/src/renderer/lib/generatedFiles.ts | 强化 Windows 路径去重 key 与画布路径归一化,减少重复 chip 与不干净路径展示/打开问题 |
| apps/desktop/src/renderer/tests/generatedFiles.test.ts | 增加针对转义残留与 UNC 的回归测试用例 |
Suppressed comments (1)
apps/desktop/src/renderer/lib/generatedFiles.ts:77
canonicalizeWindowsShape目前只处理盘符路径,UNC (\\server\share\...) 仍会把内部连续分隔符原样带下去。由于collectGeneratedFiles会保留“首次出现”的path,当第一条命令里带share\\dir这种转义残留时,最终 chip tooltip / 打开路径仍可能包含\\,与 PR 目标“路径干净”不一致。建议对 UNC 也做“保留开头\\、内部连续分隔符折叠”的归一化。
// 连续分隔符折叠进画布路径本身(不只 dedupe key):stat 虽能容忍 `C:\\x`,但
// Explorer `/select` 与 chip 展示不该带转义残留。盘符形态不存在 UNC 头,可整段折叠。
return /^[a-zA-Z]:[\\/]/.test(abs)
? abs.replace(/\//g, '\\').replace(/\\{2,}/g, '\\')
: abs;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return abs | ||
| .replace(/\//g, '\\') | ||
| .replace(/(?<!^)\\{2,}/g, '\\') | ||
| .toLowerCase(); |
| const reports = files.filter((f) => f.name === 'report.csv'); | ||
| expect(reports).toHaveLength(1); | ||
| expect(reports[0].path.startsWith('\\\\server\\')).toBe(true); | ||
| }); |
这次改了什么
摘要
「本条消息生成的文件」卡会对同一个文件出两个同名 chip。实测根因(取自真实 session 落库数据):powershell 包一层 node -e 的命令文本里,路径带转义残留(
C:\Users\...,双反斜杠);同一轮另一条命令用正斜杠形态(C:/Users/...)。二者在 fs 层是同一文件(Windows 归并重复分隔符,stat 均成功),但派生管线的去重 key 只折叠/→\与大小写、不折叠连续反斜杠 → 两个 key → 两个 chip。修复:
dedupeKeyForPath对 Windows 形态折叠连续分隔符(UNC 头部\保留);canonicalizeWindowsShape对盘符路径把画布路径本身一并折叠——chip tooltip、Explorer 定位、打开拿到干净的单反斜杠形态,MessageStream 与变更卡 exactPaths 的抑制比对也能对上。POSIX 路径一律不动(维持 PR #1835 的「宁可 macOS 偶尔重复,不在 Linux 丢文件」取舍)。变更类型
fix缺陷修复范围
generatedFiles.ts两个归一化函数 + 回归测试\转义残留UI 变化
不涉及:纯数据派生层修复,无视觉/交互/文案变化。
怎么验证的
自动验证
新增回归测试 2 例:转义包装串双反斜杠与正斜杠形态收敛为单 chip 且路径干净;UNC 头部
\保留、内部连续分隔符折叠。手工验证
用触发该 bug 的真实 session(8e2e9a6b…)落库消息离线重放派生管线:修复前 registry.json 出 2 条,修复后 1 条、路径为干净单反斜杠形态。
未执行的验证
风险
风险分类
影响与回滚
提交前检查
git commit -s)🤖 Generated with Claude Code